package cn.redsoft.wechatapi.common.util;

import java.io.Writer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.redsoft.wechatapi.msg.resp.passivity.PassivityResponseMsg;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;

public class XMLFormater {
	protected Logger logger = LoggerFactory.getLogger(XMLFormater.class);
	protected static String PREFIX_CDATA = "<![CDATA[";
	protected static String SUFFIX_CDATA = "]]>";

	private static XStream xstreamInstance = new XStream(new XppDriver() {
		public HierarchicalStreamWriter createWriter(Writer out) {
			return new PrettyPrintWriter(out) {
				boolean cdata = true;

				public void startNode(String name,
						@SuppressWarnings("rawtypes") Class clazz) {
					super.startNode(name, clazz);
				}

				protected void writeText(QuickWriter writer, String text) {
					if (cdata) {
						writer.write(PREFIX_CDATA);
						writer.write(text);
						writer.write(SUFFIX_CDATA);
					} else {
						writer.write(text);
					}
				}
			};
		}
	});

	private XStream xstream = new XStream(new XppDriver() {
		public HierarchicalStreamWriter createWriter(Writer out) {
			return new PrettyPrintWriter(out) {
				boolean cdata = true;

				public void startNode(String name,
						@SuppressWarnings("rawtypes") Class clazz) {
					super.startNode(name, clazz);
				}

				protected void writeText(QuickWriter writer, String text) {
					if (cdata) {
						writer.write(PREFIX_CDATA);
						writer.write(text);
						writer.write(SUFFIX_CDATA);
					} else {
						writer.write(text);
					}
				}
			};
		}
	});

	public String format(PassivityResponseMsg baseMsg)
			throws UnsupportedOperationException {
		return this.format(baseMsg, true);
	}

	public String object2Xml(Object obj) {
		xstream.processAnnotations(obj.getClass()); // 通过注解方式的，一定要有这句话
		return xstream.toXML(obj);
	}

	public String object2XmlAndNull2Empty(Object obj) {
		if (obj == null)
			return "";
		return this.object2Xml(obj);
	}

	public String format(PassivityResponseMsg baseMsg,
			boolean alredyReverseFromAndTo)
			throws UnsupportedOperationException {

		if (!alredyReverseFromAndTo) {
			String f = baseMsg.getFromUserName();
			baseMsg.setFromUserName(baseMsg.getToUserName());
			baseMsg.setToUserName(f);
		}

		return this.object2Xml(baseMsg);
	}

	public static String objectToXml(Object obj) {
		xstreamInstance.processAnnotations(obj.getClass()); // 通过注解方式的，一定要有这句话
		return xstreamInstance.toXML(obj);
	}

	public static String objectToXmlAndNullToEmpty(Object obj) {
		if (obj == null)
			return "";
		return objectToXml(obj);
	}
}
